


package com.lkm.app_ui.help;

import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;

import com.felhr.usbserial.UsbSerialDevice;
import com.felhr.usbserial.UsbSerialInterface;
import com.lkm.app_ui.log.SystemLogger;
import com.lkm.javatool.CollectionHelp;
import com.lkm.javatool.lang.ListRingBuffer;
import com.lkm.javatool.lang.RingBlockBuffer;
import com.lkm.javatool.lang.RingBuffer;
import com.lkm.usb_com.UsbModule;

import java.io.IOException;

public class CdcAcm {
    private RingBuffer mBuffer;

    private UsbDevice mUsbDevice;
    private static final int RING_BUFFER_SIZE = 1024;
    private static final int USB_READ_BUFFER_SIZE = 256;
    private static final int USB_WRITE_BUFFER_SIZE = 256;

    UsbSerialDevice serialPort;
    boolean serialPortConnected = false;

    public CdcAcm(UsbDevice usbDevice) {
        mUsbDevice = usbDevice;


        mBuffer = new RingBlockBuffer(new ListRingBuffer(RING_BUFFER_SIZE));
    }

    public UsbDevice getUsbDevice() {
        return mUsbDevice;
    }

    public boolean open() {
        if (open(mUsbDevice)) return true;
        return false;
    }

    public boolean open(UsbDevice usbDevice) {

        UsbDeviceConnection connection = UsbModule.getInstance().getUsbManager().openDevice(usbDevice);

        try {
            serialPort = UsbSerialDevice.createUsbSerialDevice(usbDevice, connection);
        }catch (Exception e){};
        if (serialPort != null) {
            if (serialPort.open()) {
                serialPortConnected = true;
                serialPort.setBaudRate(115200);
                serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
                serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
                serialPort.setParity(UsbSerialInterface.PARITY_NONE);
                

                serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
                serialPort.read(mCallback);
                serialPort.getCTS(ctsCallback);
                serialPort.getDSR(dsrCallback);


            } else {
                return false;

            }
        } else {
            return false;
        }
        return true;
    }

    private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
        @Override
        public void onReceivedData(byte[] rbuf) {
            try {

                int len = rbuf.length;

                SystemLogger.UsbCDC.onRead(len);

                mBuffer.add(CollectionHelp.asByteArray(rbuf, new Byte[len], len), 0, len);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    

    private UsbSerialInterface.UsbCTSCallback ctsCallback = new UsbSerialInterface.UsbCTSCallback() {
        @Override
        public void onCTSChanged(boolean state) {
        }
    };

    

    private UsbSerialInterface.UsbDSRCallback dsrCallback = new UsbSerialInterface.UsbDSRCallback() {
        @Override
        public void onDSRChanged(boolean state) {
        }
    };


    public boolean close() {

        serialPort.close();

        serialPortConnected = false;
        try {
            mBuffer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return true;
    }


    public int read(byte[] buf, int size) {
        size = Math.min(mBuffer.getBufferdLength(), size);
        if (size == 0) return 0;
        
        Byte[] tempBs = new Byte[size];
        int len = mBuffer.get(tempBs, 0, size);


        if (len != 0)
            CollectionHelp.asbyteArray(tempBs, buf, len);
        return len;
    }


    public int write(byte[] buf) {
        if (serialPort != null) {
            serialPort.write(buf);
            return buf.length;
        }

        return -1;
    }


    public boolean isOpened() {
        return serialPortConnected;
    }

    

    public boolean setBaudrate(int baudrate) {
        if (serialPort == null) return false;
        serialPort.setBaudRate(baudrate);
        return true;
    }

    

    public boolean setDataBits(int dataBits) {
        if (serialPort == null) return false;
        serialPort.setDataBits(dataBits);
        return true;
    }

    

    public boolean setParity(int parity) {
        if (serialPort == null) return false;
        serialPort.setParity(parity);
        return true;
    }

    

    public boolean setStopBits(int stopBits) {
        if (serialPort == null) return false;
        serialPort.setStopBits(stopBits);
        return false;
    }

    public boolean setDtrRts(boolean dtrOn, boolean rtsOn) {
        if (serialPort == null) return false;
        serialPort.setDTR(dtrOn);
        serialPort.setRTS(rtsOn);
        return true;
    }


}
